package com.khotyn.heresy.controller;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.khotyn.heresy.bean.HeresyErrorMessage;
import com.khotyn.heresy.bean.RegisterBean;
import com.khotyn.heresy.bean.UserDetail;
import com.khotyn.heresy.dao.UserDAO;
import com.khotyn.heresy.service.PasswordService;
import com.khotyn.heresy.util.MD5Util;
import com.khotyn.heresy.util.SendMail;
import com.khotyn.heresy.validator.RegisterValidator;
import com.khotyn.heresy.validator.UserDetailValidator;

/**
 * 注册页面控制器，用于控制注册流程，包括最后填写详细注册信息
 * 
 * @author 金灵杰
 * 
 */
@Controller
@SessionAttributes("validateCode")
public class RegisterController {
	@Autowired
	private UserDAO userDAO;

	@Autowired
	private SendMail sendMail;

	@Autowired
	private PasswordService passwordService;

	@Autowired
	private RegisterValidator registerValidator; // 注册表单验证器

	/**
	 * 初始化注册页面，并显示
	 * 
	 * @param model 初始化初始页面中绑定的对象
	 * @return 注册页面的模板名称
	 */
	@RequestMapping(value = "/register.html", method = RequestMethod.GET)
	public String setupRegisterForm(ModelMap model) {
		RegisterBean register = new RegisterBean();
		model.addAttribute("registerBean", register);
		return "register";
	}

	/**
	 * 处理注册表单数据
	 * 
	 * @param userInfo 用户提交的表单数据
	 * @param request http请求信息
	 * @param model 用户绑定页面对象
	 * @param validateCode 系统生成的验证码
	 * @param result 验证器验证后的结果
	 * @return 表单处理结束后返回的页面
	 */
	@RequestMapping(value = "/register.html", method = RequestMethod.POST)
	public String registerUser(@ModelAttribute("registerBean") RegisterBean userInfo, BindingResult result, HttpServletRequest request,
			ModelMap model, @ModelAttribute("validateCode") String validateCode) {
		// 验证验证码是否正确
		if (!validateCode.equals(userInfo.getValidateCode().toUpperCase())) {
			result.rejectValue("validateCode", "validator.error", "验证码不正确");
			return "register";
		}

		// 验证用户名、密码是否符合要求，邮箱是否已经注册
		registerValidator.validate(userInfo, result);
		if (result.hasErrors()) {
			return "register";
		}

		Random rand = new Random();
		String randomCode = Long.toString(Math.abs(rand.nextLong()), 36);
		userInfo.setActiveUrl(new String(randomCode));

		// 生成注册时间
		userInfo.setRegisterTime(new Date());

		// 加入数据库
		userInfo.setPassword(MD5Util.EncoderByMd5(userInfo.getPassword().getBytes()));
		userDAO.insertRegisterBean(userInfo);

		String path = request.getSession().getServletContext().getRealPath(".");
		try {
			String textTemp = "";
			BufferedReader buffer = new BufferedReader(new FileReader(path + "/emailTemplate/registerEmail.html"));
			String str;
			while ((str = buffer.readLine()) != null) {
				textTemp += str;
			}
			String activeUrl = "action=register&email=" + URLEncoder.encode(userInfo.getEmail(), "utf-8") + "&code="
					+ URLEncoder.encode(userInfo.getActiveUrl(), "utf-8");
			String text = String.format(textTemp, userInfo.getEmail(), request.getScheme() + "://" + request.getRemoteHost() + ":"
					+ request.getLocalPort() + request.getContextPath() + "/active.html" + "?" + activeUrl);
			sendMail.send(userInfo.getEmail(), "shutter网络相册注册", text);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		HeresyErrorMessage message = new HeresyErrorMessage("注册邮件已发送，请接收邮件后完成注册", "注册成功", "index.html");
		model.addAttribute("message", message);
		return "message";
	}

	/**
	 * 初始化用户激活表单
	 * 
	 * @param email 用户所使用的邮箱
	 * @param code 用户验证码
	 * @param model 用于返回视图时使用的模型
	 * @return 返回的视图，如果是非激活用户，则重定向到注册页面。
	 */
	@RequestMapping(value = "/active.html", method = RequestMethod.GET, params = "action=register")
	public String setupUserInfoForm(@RequestParam(value = "email", required = false) String email,
			@RequestParam(value = "code", required = false) String code, ModelMap model) {
		if (email == null || code == null) {
			return "redirect:/register.html";
		}

		UserDetail userDetail = userDAO.selectUserByEmail(email);
		if (userDetail != null && userDetail.getFlagActive().equalsIgnoreCase("actived")) {
			HeresyErrorMessage message = new HeresyErrorMessage("您已经注册，可直接用该帐号登录", "已经注册", "login.html");
			model.addAttribute("message", message);
			return "message";
		}

		if (userDetail != null && userDetail.getActiveUrl().equals(code)) {
			model.addAttribute("userDetail", userDetail);
			return "userinfo";
		}

		return "redirect:/register.html";
	}

	/**
	 * 激活用户
	 * 
	 * @param userDetail 用户详细信息
	 * @param result 表单验证结果
	 * @param model 传递数据的模型
	 * @param oldPassword 用户原密码
	 * @param session 如果激活成功，存放用户id，作为登录用户
	 * @return 处理后返回的视图，激活成功返回信息页面，并重定向到用户主页；激活失败返回用户详细信息输入页面
	 */
	@RequestMapping(value = "/active.html", method = RequestMethod.POST)
	public String activeUser(@ModelAttribute("userDetail") UserDetail userDetail, BindingResult result, ModelMap model,
			@RequestParam(value = "oldPassword", required = false) String oldPassword, HttpSession session) {
		// 使用验证器验证表单数据
		new UserDetailValidator().validate(userDetail, result);
		if (result.hasErrors()) {
			return "userinfo";
		}

		// 用户需要同时修改密码
		if (!userDetail.getPassword().isEmpty() && oldPassword != null) {
			if (!passwordService.changePassword(oldPassword, userDetail)) {
				model.addAttribute("errorPasswordStr", "原密码错误，请重新输入");
				return "userinfo";
			}
		}

		// FIXME:需要加入事务处理

		userDetail.setFlagActive("actived");

		userDAO.updateFlagActive(userDetail);
		userDAO.updateUser(userDetail);

		// 将用户id放入session，用户不用再次登录
		session.setAttribute("userID", userDetail.getUserID());

		HeresyErrorMessage message = new HeresyErrorMessage("注册成功，现在返回您的首页", "注册成功", "user.html?userID=" + userDetail.getUserID());
		model.addAttribute("message", message);
		return "message";
	}

	/**
	 * 设置表单中日期的格式化方法
	 * 
	 * @param binder 用于绑定表单数据格式化方法
	 */
	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
	}
}
